/*
 * Copyright (c) 2009, Jan Pastor. All Rights Reserved.
 */

package sk.jp.commons.ui;


import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.TimerTask;
import javax.swing.*;


/**
 * Modalny dialog pre blokovanie GUI pri vykonavani operacii. Obsahuje
 * progress-bar a volitelne aj tlacitko na prerusenie operacie.<br>
 * <br>
 * Kod aplikacie, ktory sa ma vykonavat pocas zobrazeneho WaitingDialog-u
 * sa musi spustit v samostatnom vlakne, aby sa rodicovske okno mohlo
 * prekreslovat.<br>
 * <u>Tu je priklad:</u><br>
 * <br><I>
 * &nbsp;&nbsp;&nbsp;&nbsp;final WaitingDialog wd = new WaitingDialog(this, "Text v dialogu...");<br>
 * <br>
 * &nbsp;&nbsp;&nbsp;&nbsp;(new Thread(){<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public void run(){<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Main.stopSubSystems();<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;wd.close();<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.exit(0);<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>
 * &nbsp;&nbsp;&nbsp;&nbsp;}).start();<br>
 * <br>
 *
 * @deprecated  //TODO Dokoncit!!! This component need to be reimplemented. Current implementation
 * is depreecated and it is not recommended for use.
 */
public class WaitingDialog extends JDialog implements Runnable {

	/**
	 * Pocet sekund na vyplnenie progress-baru.
	 */
    public static final int PB_MAX = 30;

    /**
     * Farba progress-baru (vyplne).
     */
    public static final Color pbColor = new Color(0x87, 0xCE, 0xFA);

    //------------------------------------------------------------------

    private static String title = "";
    private static String abortLabel = "Abort";

    //------------------------------------------------------------------

	/**
	 * Uloha, ktora je periodicky vykonavana - inkrementacia progress-baru.
	 */
    private class IncPB extends TimerTask {
        private JProgressBar pb;
        private int val;

		/**
		 * Inicializacia.
		 */
        public IncPB(JProgressBar pb) {
            super();
            this.pb = pb;
            val = 0;
        }

		/**
		 * Inkrementacia progress-baru.
		 */
        public void run() {
            if(val == pbMax) {
                val = 0;
            }
            pb.setValue(val++);
        }
    }

    private java.util.Timer timer;
    private JProgressBar progressbar;
    private AbortHandler abortHandler;
    private final int pbMax;

    //------------------------------------------------------------------[+s]

	/**
	 * Konfiguracia pre vsetky nasledne vytvorene dialogy.<br>
	 * <br>
	 *
	 * @param title Titulok dialogu.
	 * @param abortLabel Napis na tlacitku pre prerusenie.
	 */
    public static void configure(String title, String abortLabel){
		WaitingDialog.title = title;
		WaitingDialog.abortLabel = abortLabel;
	}

    //------------------------------------------------------------------[k]

    /**
     * Vytvory a zobrazi modalny dialog s progressbarom.<br>
     * <br>
     * Dialog je zatvarany aplikaciou, ktora ho vytvorila, metodou
     * <I>close()</I>.
     *
     * @param owner Rodicovske okno.
     * @param text Text na dialogu.
     */
    public WaitingDialog(Frame owner, String text) {
        this(owner, text, null, PB_MAX);
    }

    /**
     * Vytvory a zobrazi modalny dialog s progressbarom.<br>
     * <br>
     * Dialog je zatvarany aplikaciou, ktora ho vytvorila, metodou
     * <I>close()</I>.
     *
     * @param owner Rodicovske okno.
     * @param text Text na dialogu.
     * @param abortHandler Obsluha pre tlacitko 'Abort' (vid. interface
     * AbortHandler).
     * @param pbMax Pocet sekund pre naplnenie progress-bara.
     */
    public WaitingDialog(Frame owner, String text, AbortHandler abortHandler,
                            int pbMax) {
        super(owner, title, true);

        this.abortHandler = abortHandler;
        this.pbMax = pbMax * 2;
        timer = new java.util.Timer();
        progressbar = createProgressBar();
        constructDialog(text);

        (new Thread(this)).start();
    }

    //------------------------------------------------------------------[+]

	/**
	 * Ukoncenie a zatvorenie dialogu.
	 */
    public void close() {
        try{
        	if(timer != null)
	            timer.cancel();
	        timer = null;
        }catch(Throwable t){
            ;
        }
        dispose();
        progressbar = null;
        abortHandler = null;
    }

    //------------------------------------------------------------------[i]

	//// implementacia Runnable ////

    /**
     * <I><B>Tato metoda sa nepouziva aplikaciou, je to implementacia
	 * rozhrania Runnable.</B></I><br>
	 * <br>
	 * Zabezpeci spustenie casovaca pre inkrementaciu progress-baru a
	 * zobrazenie dialogu.
     */
    public void run() {
        try {
            timer.schedule(new IncPB(progressbar), 250, 500);  //period = 0.5 sec
            show();
        }catch(IllegalStateException ise){
            return;
        }catch(Throwable t){
			return;
		}
    }

    //------------------------------------------------------------------[-]

	/**
	 * Zostrojenie dialogu.
	 *
	 * @param text Text v dialogu.
	 */
    private void constructDialog(String text) {

        setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);

        Container p0 = getContentPane();

        JPanel p = new JPanel();
        p.setBorder(new javax.swing.border.EmptyBorder(24, 24, 24, 24));
        p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));

        JLabel ll = new JLabel(text);
        ll.setAlignmentX(Component.CENTER_ALIGNMENT);
        p.add(ll);

        JPanel pp = new JPanel();
        pp.setBorder(new javax.swing.border.EmptyBorder(8, 0, 8, 0));
        progressbar.setAlignmentX(Component.CENTER_ALIGNMENT);
        pp.add(progressbar);
        p.add(pp);

        if(abortHandler != null) {
            JButton ab = new JButton(abortLabel);
            ab.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent e){
                                abortHandler.abortHandler();
                            }});
            ab.setAlignmentX(Component.CENTER_ALIGNMENT);
            p.add(ab);
        }

        p0.add(p);

        pack();
        //Dimension sd = Toolkit.getDefaultToolkit().getScreenSize();
        Rectangle sd = getOwner().getBounds();
        Dimension dd = getSize();
        setLocation(sd.x + (sd.width - dd.width) / 2,
					sd.y + (sd.height - dd.height) / 2);
    }

	/**
	 * Zostroji progress-bar.
	 */
    private JProgressBar createProgressBar() {
        JProgressBar pb = new JProgressBar(0, pbMax);
        pb.setForeground(pbColor);
        pb.setPreferredSize(new Dimension(240, 14));
        pb.setMinimumSize(new Dimension(120, 14));
        pb.setMaximumSize(new Dimension(120, 14));
        pb.setValue(0);
        pb.setStringPainted(false);
        return pb;
    }

}